﻿using System;
using System.Collections.Generic;
using System.Threading;
using System.Net.Sockets;
using DataAccessLayer;

/*
 * int   CarId
 * double   LocationX
 * double   LocationY
 * double   Speed
 * double   OilPressure
 * double   GasPressure
 * DateTime Time (int year, int month, int day, int hour, int minute, int second)
 */
namespace ListenerServer
{
    public class Client
    {
        private Socket clientSocket;

        public void Start(Socket socket)
        {
            //create new thread
            clientSocket = socket;
            Thread clientThread = new Thread(WriteState);
            clientThread.Start();
        }

        private void WriteState()
        {
            //byte buffer to recieve information
            int bufferSize = sizeof(int) + 5*sizeof(double) + 6*sizeof(int) + sizeof(double);
            Byte[] bytesRecieved = new Byte[bufferSize];

            //recieve information
            int bytes = clientSocket.Receive(bytesRecieved, bufferSize, 0);
            clientSocket.Close();

            //write state in DB if recieved expected amount of bytes
          //  if (bytes == bufferSize)
            {

                //meaningful parts of recieved information
                Byte[] carIdBytes = new Byte[sizeof(int)];
                Byte[] xBytes = new Byte[sizeof(double)];
                Byte[] yBytes = new Byte[sizeof(double)];
                Byte[] speedBytes = new Byte[sizeof(double)];
                Byte[] oilPressureBytes = new Byte[sizeof(double)];
                Byte[] gasPressureBytes = new Byte[sizeof(double)];
                Byte[] yearBytes = new Byte[sizeof(int)];
                Byte[] monthBytes = new Byte[sizeof(int)];
                Byte[] dayBytes = new Byte[sizeof(int)];
                Byte[] hourBytes = new Byte[sizeof(int)];
                Byte[] minuteBytes = new Byte[sizeof(int)];
                Byte[] secondBytes = new Byte[sizeof(int)];
                Byte[] directionBytes = new Byte[sizeof(double)];

                //split information into parts
                int j = 0;
                for (int i = 0; i < sizeof(int); i++, j++)
                    carIdBytes[i] = bytesRecieved[j];
                for (int i = 0; i < sizeof(double); i++, j++)
                    xBytes[i] = bytesRecieved[j];
                for (int i = 0; i < sizeof(double); i++, j++)
                    yBytes[i] = bytesRecieved[j];
                for (int i = 0; i < sizeof(double); i++, j++)
                    speedBytes[i] = bytesRecieved[j];
                for (int i = 0; i < sizeof(double); i++, j++)
                    oilPressureBytes[i] = bytesRecieved[j];
                for (int i = 0; i < sizeof(double); i++, j++)
                    gasPressureBytes[i] = bytesRecieved[j];
                for (int i = 0; i < sizeof(int); i++, j++)
                    yearBytes[i] = bytesRecieved[j];
                for (int i = 0; i < sizeof(int); i++, j++)
                    monthBytes[i] = bytesRecieved[j];
                for (int i = 0; i < sizeof(int); i++, j++)
                    dayBytes[i] = bytesRecieved[j];
                for (int i = 0; i < sizeof(int); i++, j++)
                    hourBytes[i] = bytesRecieved[j];
                for (int i = 0; i < sizeof(int); i++, j++)
                    minuteBytes[i] = bytesRecieved[j];
                for (int i = 0; i < sizeof(int); i++, j++)
                    secondBytes[i] = bytesRecieved[j];
                for (int i = 0; i < sizeof(double); i++, j++)
                    directionBytes[i] = bytesRecieved[j];

                    //reverse arrays if little endian to receive right values
                    if (BitConverter.IsLittleEndian)
                    {
                        Array.Reverse(carIdBytes);
                        Array.Reverse(xBytes);
                        Array.Reverse(yBytes);
                        Array.Reverse(speedBytes);
                        Array.Reverse(oilPressureBytes);
                        Array.Reverse(gasPressureBytes);
                        Array.Reverse(yearBytes);
                        Array.Reverse(monthBytes);
                        Array.Reverse(dayBytes);
                        Array.Reverse(hourBytes);
                        Array.Reverse(minuteBytes);
                        Array.Reverse(secondBytes);
                        Array.Reverse(directionBytes);
                    }

                //convert byte arrays to correspondig argument's type
                int carId = BitConverter.ToInt32(carIdBytes, 0);
                double locationX = BitConverter.ToDouble(xBytes, 0);
                double locationY = BitConverter.ToDouble(yBytes, 0);
                double speed = BitConverter.ToDouble(speedBytes, 0);
                double oilPressure = BitConverter.ToDouble(oilPressureBytes, 0);
                double gasPressure = BitConverter.ToDouble(gasPressureBytes, 0);
                int year = BitConverter.ToInt32(yearBytes, 0);
                int month = BitConverter.ToInt32(monthBytes, 0);
                int day = BitConverter.ToInt32(dayBytes, 0);
                int hour = BitConverter.ToInt32(hourBytes, 0);
                int minute = BitConverter.ToInt32(minuteBytes, 0);
                int second = BitConverter.ToInt32(secondBytes, 0);
                double direction = BitConverter.ToDouble(directionBytes, 0);


                //add arguments into dictionary
                Dictionary<string, object> args = new Dictionary<string, object>();
                args["CarId"] = carId;
                args["LocationX"] = locationX;
                args["LocationY"] = locationY;
                args["Speed"] = speed;
                args["OilPressure"] = oilPressure;
                args["GasPressure"] = gasPressure;
                args["Time"] = new DateTime(year, month, day, hour, minute, second);
                args["Direction"] = direction;

                //write the car state in DB
                DAL.Operation("Write", "CarState", args);
            }
        }
    }
}
